from datetime import datetime

from django.contrib.auth import get_user_model, authenticate, hashers
from django.db import transaction
from django.db.models import Prefetch
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView, Response, status
from rest_framework import viewsets, mixins
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.views import TokenViewBase
from rest_framework.decorators import action
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend

from .models import Account
from .filters import AccountFilter
from .serializers import CompanySerializer, AccountSerializer
from utils.common import Pagination

User = get_user_model()


def get_tokens_for_user(user):
    refresh = RefreshToken.for_user(user)

    return {
        'refresh_token': str(refresh),
        'token': str(refresh.access_token),
    }


class LoginView(APIView):
    """
    post: 登陆，返回token
    """

    def post(self, request):
        username = request.data.get('username', '')
        password = request.data.get('password', '')
        company_name = request.data.get('company_name', '')
        login_type = request.data.get('login_type', '')
        if login_type == 'company':
            if not company_name:
                return Response({'message': '需要企业名称'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                user = Account.objects.get(username=company_name, is_company=True)
                if not hashers.check_password(password, user.password):
                    return Response({'message': '密码错误'}, status=status.HTTP_400_BAD_REQUEST)
            except Account.DoesNotExist:
                return Response({'message': '不存在该企业'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            try:
                user = Account.objects.get(username=username, is_company=False)
                if not hashers.check_password(password, user.password):
                    return Response({'message': '密码错误'}, status=status.HTTP_400_BAD_REQUEST)
            except Account.DoesNotExist:
                return Response({'message': '账号错误'}, status=status.HTTP_400_BAD_REQUEST)

        response_data = get_tokens_for_user(user)
        user.last_login = datetime.now()
        user.save()

        return Response({'data': response_data}, status=status.HTTP_200_OK)


class UserInfoView(APIView):
    """
    get:
        获取用户信息
    """
    permission_classes = [IsAuthenticated, ]

    def get(self, request):
        """
        返回用户的信息
        权限列表，roles: ['perm1','perm2',...]
        """
        user = request.user
        name = user.username if user.is_company else user.realname
        perms_set = user.get_all_perms()
        perms = list(perms_set) if perms_set else ['nothing']
        res_data = {'name': name, 'roles': perms, 'ying_ji': user.ying_ji, 'jian_kong': user.jian_kong}
        return Response({'data': res_data}, status=status.HTTP_200_OK)


class CompanyViewSet(mixins.ListModelMixin,
                     viewsets.GenericViewSet):
    queryset = Account.objects.filter(is_company=True).order_by('id')\
        .only('username', 'id', 'is_company')
    serializer_class = CompanySerializer
    filter_class = AccountFilter
    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)


class AccountViewSet(viewsets.GenericViewSet,
                     mixins.ListModelMixin):
    queryset = Account.objects.all()
    pagination_class = Pagination
    serializer_class = AccountSerializer
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
    filter_class = AccountFilter
    ordering_fields = ('id',)

    @action(methods=['patch'], detail=False, url_path='reset_self_password')
    def reset_self_password(self, request, pk=None):
        """ 修改个人的密码 """
        old_password = request.data.get('old_password', None)
        new_password = request.data.get('new_password', None)
        if not old_password or not new_password:
            return Response({'message': '错误：需要新密码和旧密码'}, status=status.HTTP_400_BAD_REQUEST)
        user = request.user
        if not user.check_password(old_password):
            return Response({'message': '旧密码错误，请输入正确的旧密码'}, status=status.HTTP_400_BAD_REQUEST)
        user.set_password(new_password)
        user.save()
        return Response({'message': '修改密码成功'}, status=status.HTTP_200_OK)

    @action(methods=['patch'], detail=True, url_path='reset_user_password')
    def reset_user_password(self, request, pk=None):
        """
            修改用户的密码
        :pk: 用户id, 需要
        :new_password: 新密码，需要
        """
        if not request.user.is_superuser:
            return Response({'message': '只有管理员才能修改密码'}, status=status.HTTP_403_FORBIDDEN)
        new_password = request.data.get('new_password', None)
        user = User.objects.filter(id=pk).first()
        if not user:
            return Response({'message': '错误：需要正确的id'}, status=status.HTTP_400_BAD_REQUEST)
        if user.is_superuser and request.user.id != user.id:
            return Response({'message': '无法修改其他管理员的密码'}, status=status.HTTP_403_FORBIDDEN)
        user.set_password(new_password)
        user.save()
        return Response({'message': '重置密码成功'}, status=status.HTTP_200_OK)
